<!DOCTYPE html><html lang="en" data-beasties-container><head>
  <meta charset="UTF-8">
  <title>Get Started</title>
  <meta name="description" content="Djongo overcomes common pitfalls of PyMongo programming. It maps python objects to MongoDB documents. Setting up the mapping documents to python objects is easy with Djongo.">
  <meta name="keywords" content="Django, MongoDB, Django MongoDB connector, Object document mapper">
  <meta property="og:type" content="website">
  <meta property="og:locale" content="en_US">
  <meta property="og:site_name" content="Djongomapper">
  <meta property="og:title" content="Djongo">
  <meta property="og:url" content="https://www.djongomapper.com/">
  <meta property="og:description" content="Djongo overcomes common pitfalls of PyMongo programming. It maps python objects to MongoDB documents. Setting up the mapping documents to python objects is easy with Djongo.">
  <link rel="canonical" href="https://www.djongomapper.com/">
  <script type="application/ld+json">
    {
      "@context": "https://schema.org",
      "@type": "Organization",
      "name": "Doableware",
      "url": "https://www.djongomapper.com/",
      "logo": "/assets/images/djongo-symbol-small.png"
    }
  </script>
  <meta name="google-site-verification" content="tFNu7Nc9hzKF9v7f6kYaoMbBCNyGREchcKMVdxJuyJo">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <link rel="preload" href="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@5/css/all.min.css" as="style" onload="this.onload=null;this.rel='stylesheet'">
  <noscript>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@5/css/all.min.css">
  </noscript>
  <link rel="stylesheet" type="text/css" media="screen" href="/assets/css/styles.css">
  <link rel="shortcut icon" href="/assets/images/favicon.ico">
  <script>
    if (window.location.hostname != 'localhost') {
      (function (w, d, s, l, i) {
        w[l] = w[l] || [];
        w[l].push({
                    'gtm.start':
                      new Date().getTime(), event: 'gtm.js'
                  });
        var f = d.getElementsByTagName(s)[0],
          j = d.createElement(s), dl = l != 'dataLayer' ? '&l=' + l : '';
        j.async = true;
        j.src =
          'https://www.googletagmanager.com/gtm.js?id=' + i + dl;
        f.parentNode.insertBefore(j, f);
      })(window, document, 'script', 'dataLayer', 'GTM-T72KG6N');
    }
  </script>
  <base href="/">
<link rel="stylesheet" href="styles-JF5ME2K6.css" media="print" onload="this.media='all'"><noscript><link rel="stylesheet" href="styles-JF5ME2K6.css"></noscript><style ng-app-id="ng">.cookie-notice[_ngcontent-ng-c2830357685]{height:0}.open[_ngcontent-ng-c2830357685]{height:auto}.close[_ngcontent-ng-c2830357685]{height:0;transition:height .3s ease-out}.mast[_ngcontent-ng-c2830357685]{position:sticky;top:0;padding:.5em 0;z-index:10;background:#fff;border-bottom:1px solid rgb(241.7553,242.60496,243.2547)}@media (max-width: 90rem){.mast[_ngcontent-ng-c2830357685]{padding:.5em 1em}}.mast[_ngcontent-ng-c2830357685] > div[_ngcontent-ng-c2830357685]{margin:0 auto;max-width:80rem;display:flex;flex-direction:row;justify-content:space-between}.mast[_ngcontent-ng-c2830357685]   a[_ngcontent-ng-c2830357685]{display:block;color:#62696e;text-decoration:none}.mast[_ngcontent-ng-c2830357685]   .mast-logo[_ngcontent-ng-c2830357685]{display:flex;gap:var(--space-xs);align-items:center}.mast[_ngcontent-ng-c2830357685]   .mast-logo[_ngcontent-ng-c2830357685]   img[_ngcontent-ng-c2830357685]{max-height:2em}.mast[_ngcontent-ng-c2830357685]   .mast-nav[_ngcontent-ng-c2830357685]   ul[_ngcontent-ng-c2830357685]{display:flex;align-items:center;gap:var(--space-md)}.mast[_ngcontent-ng-c2830357685]   .mast-nav[_ngcontent-ng-c2830357685]   ul.media-small[_ngcontent-ng-c2830357685]{padding-top:var(--space-sm);padding-bottom:var(--space-sm);flex-direction:column;align-items:start;gap:var(--space-xs)}.mast[_ngcontent-ng-c2830357685]   .mast-nav[_ngcontent-ng-c2830357685]   .nav-link[_ngcontent-ng-c2830357685]{position:relative}.mast[_ngcontent-ng-c2830357685]   .mast-nav[_ngcontent-ng-c2830357685]   .nav-link[_ngcontent-ng-c2830357685]:hover:after{width:100%}.mast[_ngcontent-ng-c2830357685]   .mast-nav[_ngcontent-ng-c2830357685]   .nav-link[_ngcontent-ng-c2830357685]:after{content:"";position:absolute;left:50%;bottom:0;transform:translate(-50%);width:0;height:4px;background-color:#62696e;transition:width .2s ease-in-out}.mast[_ngcontent-ng-c2830357685]   .mast-nav[_ngcontent-ng-c2830357685]   .btn-nav[_ngcontent-ng-c2830357685]{padding:.5em 1em;font-size:var(--font-sm);font-weight:700;text-align:center;border-width:0;border-radius:.1875em;color:#fff}.burger[_ngcontent-ng-c2830357685]{display:flex;flex-direction:column;gap:4px}.burger[_ngcontent-ng-c2830357685] > div[_ngcontent-ng-c2830357685]{height:4px;width:var(--space-md);background-color:#62696e;border-radius:4px}.burger[_ngcontent-ng-c2830357685]:hover{cursor:pointer}</style><style ng-app-id="ng">.media-small[_ngcontent-ng-c40719357]{position:fixed;top:3rem;left:0;padding:0 var(--space-sm);background:#fff;height:100vh;border-right:1px solid rgb(241.7553,242.60496,243.2547);z-index:1}.cross[_ngcontent-ng-c40719357]{margin:var(--space-2xs) 0;aspect-ratio:1;width:var(--font-md)}.cross[_ngcontent-ng-c40719357]:hover{cursor:pointer}.cross[_ngcontent-ng-c40719357] > div[_ngcontent-ng-c40719357]{background:#000;height:1px;width:var(--font-md)}.cross[_ngcontent-ng-c40719357] > div[_ngcontent-ng-c40719357]:nth-child(1){transform:translateY(calc(var(--font-md) * .5)) rotate(-45deg)}.cross[_ngcontent-ng-c40719357] > div[_ngcontent-ng-c40719357]:nth-child(2){transform:translateY(calc(var(--font-md) * .5 - 1px)) rotate(45deg)}.open[_ngcontent-ng-c40719357]{transition:transform .4s ease-in;transform:translate(0)}.close[_ngcontent-ng-c40719357]{transform:translate(-100%);padding:0;overflow:hidden;transition:transform .3s ease-out}</style><style ng-app-id="ng">.body[_ngcontent-ng-c2889142148]{display:grid;grid-template-columns:minmax(max-content,calc(16rem - 1em)) minmax(16rem,80rem) minmax(min-content,calc(16rem - 1em));grid-template-rows:repeat(2,auto);justify-content:center;column-gap:1em;padding-left:1em;padding-right:1em}.page-content[_ngcontent-ng-c2889142148]{grid-row:1/-1}.aside-left[_ngcontent-ng-c2889142148], .aside-right[_ngcontent-ng-c2889142148]{grid-row:1}@media (max-width: 80rem){.body[_ngcontent-ng-c2889142148]{grid-template-columns:max-content minmax(24rem,80rem);grid-template-rows:repeat(3,auto)}.aside-left[_ngcontent-ng-c2889142148]{grid-column:1;grid-row:1/3}.page-content[_ngcontent-ng-c2889142148]{grid-column:2;grid-row:2/-1}.aside-right[_ngcontent-ng-c2889142148]{grid-column:2;grid-row:1/2}}@media (max-width: 48rem){.body[_ngcontent-ng-c2889142148]{grid-template-rows:repeat(2,auto)}.aside-left[_ngcontent-ng-c2889142148]{grid-row:1/-1}.aside-right[_ngcontent-ng-c2889142148]{grid-row:1}.page-content[_ngcontent-ng-c2889142148]{grid-row:2}}.nav[_ngcontent-ng-c2889142148]{padding-top:1em;padding-bottom:1em;min-width:min-content;max-width:max-content;font-size:var(--font-sm)}@media (max-width: 80rem){.nav[_ngcontent-ng-c2889142148]{font-size:var(--font-base)}}.nav[_ngcontent-ng-c2889142148]   a[_ngcontent-ng-c2889142148]{text-decoration:none}.nav-sticky[_ngcontent-ng-c2889142148]{position:sticky;top:3em;overflow:auto;max-height:calc(100vh - 3em)}.nav-sticky.aside-left[_ngcontent-ng-c2889142148]{z-index:1}@media (max-width: 80rem){.nav-sticky.aside-right[_ngcontent-ng-c2889142148]{position:static;max-height:inherit}}.nav-side[_ngcontent-ng-c2889142148]{line-height:1.58}.nav-side[_ngcontent-ng-c2889142148]   h3[_ngcontent-ng-c2889142148]{font-size:1em;opacity:.7;text-transform:uppercase;border-bottom:1px solid rgb(241.7553,242.60496,243.2547);margin:.5em 0;padding:.25em 0}.nav-side[_ngcontent-ng-c2889142148]   a[_ngcontent-ng-c2889142148]{color:inherit;opacity:.7}.nav-side[_ngcontent-ng-c2889142148]   .active[_ngcontent-ng-c2889142148]{font-weight:700;opacity:1}.nav-side[_ngcontent-ng-c2889142148]   a[_ngcontent-ng-c2889142148]:hover{opacity:1}.nav-toc[_ngcontent-ng-c2889142148]   h3[_ngcontent-ng-c2889142148]{font-size:var(--font-base);font-weight:700;color:#fff;background:#62696e;border-top-left-radius:.375em;border-top-right-radius:.375em;padding:var(--space-2xs) var(--space-xs);margin:0}.nav-toc[_ngcontent-ng-c2889142148]   a[_ngcontent-ng-c2889142148]{display:block;padding:var(--space-2xs) var(--space-xs);color:#646769;font-weight:700;line-height:1.5;border-bottom:1px solid rgb(241.7553,242.60496,243.2547);border-left:1px solid rgb(241.7553,242.60496,243.2547);border-right:1px solid rgb(241.7553,242.60496,243.2547)}.nav-toc[_ngcontent-ng-c2889142148]   a[_ngcontent-ng-c2889142148]:hover{text-decoration:underline}.nav-toc[_ngcontent-ng-c2889142148]   li[_ngcontent-ng-c2889142148]   li[_ngcontent-ng-c2889142148] > a[_ngcontent-ng-c2889142148]{font-weight:400;padding-left:1em}.nav-toc[_ngcontent-ng-c2889142148]   .active[_ngcontent-ng-c2889142148]{background-color:#e2e4e5}.sidebar[_ngcontent-ng-c2889142148]{opacity:1}.sidebar[_ngcontent-ng-c2889142148]   li[_ngcontent-ng-c2889142148]{font-size:.7em}.page-content[_ngcontent-ng-c2889142148]{margin-top:1em}</style></head>
<body><!--nghm--><script type="text/javascript" id="ng-event-dispatch-contract">(()=>{function p(t,n,r,o,e,i,f,m){return{eventType:t,event:n,targetElement:r,eic:o,timeStamp:e,eia:i,eirp:f,eiack:m}}function u(t){let n=[],r=e=>{n.push(e)};return{c:t,q:n,et:[],etc:[],d:r,h:e=>{r(p(e.type,e,e.target,t,Date.now()))}}}function s(t,n,r){for(let o=0;o<n.length;o++){let e=n[o];(r?t.etc:t.et).push(e),t.c.addEventListener(e,t.h,r)}}function c(t,n,r,o,e=window){let i=u(t);e._ejsas||(e._ejsas={}),e._ejsas[n]=i,s(i,r),s(i,o,!0)}window.__jsaction_bootstrap=c;})();
</script><script>window.__jsaction_bootstrap(document.body,"ng",["click"],[]);</script>
<app-root ng-version="20.1.4" _nghost-ng-c2830357685 ngh="3" ng-server-context="ssg"><div _ngcontent-ng-c2830357685 class="page-splash"><div _ngcontent-ng-c2830357685 class="mast"><div _ngcontent-ng-c2830357685><div _ngcontent-ng-c2830357685 class="mast-logo"><a _ngcontent-ng-c2830357685 href="/"><img _ngcontent-ng-c2830357685 src="/assets/images/djongo-symbol-small.png" alt="Djongo"></a><!----></div><div _ngcontent-ng-c2830357685 class="mast-nav"><app-nav _ngcontent-ng-c2830357685 _nghost-ng-c40719357 ngh="0"><!----><!----><!----></app-nav></div></div></div><div _ngcontent-ng-c2830357685 class="initial-content"><router-outlet _ngcontent-ng-c2830357685></router-outlet><ng-component _nghost-ng-c2889142148 ngh="2"><div _ngcontent-ng-c2889142148 class="body"><aside _ngcontent-ng-c2889142148 class="nav-sticky aside-left"><app-nav _ngcontent-ng-c2889142148 _nghost-ng-c40719357 ngh="0"><!----><!----><!----></app-nav></aside><div _ngcontent-ng-c2889142148 class="page-content"><header _ngcontent-ng-c2889142148><h1 _ngcontent-ng-c2889142148 class="title-docs">Get Started</h1></header><router-outlet _ngcontent-ng-c2889142148></router-outlet><ng-component ngh="1"><h2 id="install">Install</h2><ul><li>Install the latest version of djongo from: </li></ul><div appcodecopy class="highlighter-rouge highlight codehilite"><pre><span></span><code><span class="w">  </span>pip<span class="w"> </span>install<span class="w"> </span>--extra-index-url<span class="w"> </span>https://pypi.djongomapper.com/latest-updates/<span class="w"> </span>djongo
</code></pre><img alt="copy code" src="/assets/images/copy.svg" class="docs-copy"></div><ul><li>Into <code>settings.py</code> file of your project, add:</li></ul><div appcodecopy class="highlighter-rouge highlight codehilite"><pre><span></span><code>  <span class="n">DATABASES</span> <span class="o">=</span> <span class="p">{</span>
      <span class="s1">'default'</span><span class="p">:</span> <span class="p">{</span>
          <span class="s1">'ENGINE'</span><span class="p">:</span> <span class="s1">'djongo'</span><span class="p">,</span>
          <span class="s1">'NAME'</span><span class="p">:</span> <span class="s1">'your-db-name'</span><span class="p">,</span>
      <span class="p">}</span>
  <span class="p">}</span>
</code></pre><img alt="copy code" src="/assets/images/copy.svg" class="docs-copy"></div><h3 id="prerequisites">Prerequisites</h3><ul><li>You have a DjongoCS account.</li><li>Your <a fragment="generate-access-token" href="/docs/get-started#generate-access-token" jsaction="click:;">access tokens</a> have been successfully setup.</li><li>Alternatively, you can install an older version directly from pypi:</li></ul><div appcodecopy class="highlighter-rouge highlight codehilite"><pre><span></span><code><span class="w">  </span>pip<span class="w"> </span>install<span class="w"> </span>djongo
</code></pre><img alt="copy code" src="/assets/images/copy.svg" class="docs-copy"></div><ul><li>Or, from github:</li></ul><div appcodecopy class="highlighter-rouge highlight codehilite"><pre><span></span><code>pip<span class="w"> </span>install<span class="w"> </span>git+https://github.com/djongo/djongo.git
</code></pre><img alt="copy code" src="/assets/images/copy.svg" class="docs-copy"></div><h2 id="models">Models</h2><p>A Model is the single, canonical source of information about the data your application stores.
It is defined as a Python class that subclasses <code>djongo.models.Model</code>. Each attribute of the class represents a MongoDB <a href="https://www.mongodb.com/docs/manual/core/document/#document-structure">document field</a>.</p><p>Each model maps to one MongoDB collection and encapsulates the structure and behavior of that collection in one place. Because models are plain Python classes, you can add helper methods and properties to encapsulate domain logic close to the data they operate on. </p><p>Defining models in code makes your schema explicit, reviewable, and easy to test. More details on models can be found <a href="https://docs.djangoproject.com/en/dev/topics/db/models/">here</a></p><div appcodecopy class="highlighter-rouge highlight codehilite"><pre><span></span><code><span class="kn">from</span> <span class="nn">djongo</span> <span class="kn">import</span> <span class="n">models</span>

<span class="k">class</span> <span class="nc">Article</span><span class="p">(</span><span class="n">models</span><span class="o">.</span><span class="n">Model</span><span class="p">):</span>
    <span class="n">title</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">CharField</span><span class="p">(</span><span class="n">max_length</span><span class="o">=</span><span class="mi">200</span><span class="p">)</span>
    <span class="n">body</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">TextField</span><span class="p">()</span>
    <span class="n">published_on</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">DateTimeField</span><span class="p">(</span><span class="n">null</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">blank</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
</code></pre><img alt="copy code" src="/assets/images/copy.svg" class="docs-copy"></div><h2 id="fields">Fields</h2><p><a href="https://docs.djangoproject.com/en/dev/topics/db/models/#fields">Fields</a> are the building blocks of models. Djongo supports all of Django field types, for example
<code>CharField</code>, <code>TextField</code>, <code>IntegerField</code>, <code>BooleanField</code>, and <code>DateTimeField</code>. Each field accepts options such as max_length, blank, null, default, and choices
to control validation and storage behavior. </p><p>Models also express relationships at the schema level using <code>ForeignKey</code>, <code>OneToOneField</code>, and <code>ManyToManyField</code>. The inner Meta class lets you provide model-wide configuration such as verbose_name, custom database table names, and ordering preferences. </p><p>Djongo adds extra fields for supporting MongoDB features
like <a href="https://www.mongodb.com/docs/manual/core/document/#embedded-documents">embedded documents</a>.</p><div appcodecopy class="highlighter-rouge highlight codehilite"><pre><span></span><code><span class="kn">from</span> <span class="nn">djongo</span> <span class="kn">import</span> <span class="n">models</span>

<span class="k">class</span> <span class="nc">Author</span><span class="p">(</span><span class="n">models</span><span class="o">.</span><span class="n">Model</span><span class="p">):</span>
    <span class="n">name</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">CharField</span><span class="p">(</span><span class="n">max_length</span><span class="o">=</span><span class="mi">100</span><span class="p">)</span>

<span class="k">class</span> <span class="nc">Post</span><span class="p">(</span><span class="n">models</span><span class="o">.</span><span class="n">Model</span><span class="p">):</span>
    <span class="n">author</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">ForeignKey</span><span class="p">(</span><span class="n">Author</span><span class="p">,</span> <span class="n">on_delete</span><span class="o">=</span><span class="n">models</span><span class="o">.</span><span class="n">CASCADE</span><span class="p">)</span>
    <span class="n">title</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">CharField</span><span class="p">(</span><span class="n">max_length</span><span class="o">=</span><span class="mi">255</span><span class="p">)</span>
    <span class="n">tags</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">ManyToManyField</span><span class="p">(</span><span class="s1">'Tag'</span><span class="p">,</span> <span class="n">blank</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>

    <span class="k">class</span> <span class="nc">Meta</span><span class="p">:</span>
        <span class="n">verbose_name</span> <span class="o">=</span> <span class="s2">"blog post"</span>
        <span class="n">ordering</span> <span class="o">=</span> <span class="p">[</span><span class="s1">'-id'</span><span class="p">]</span>
</code></pre><img alt="copy code" src="/assets/images/copy.svg" class="docs-copy"></div><h3 id="embeddedfield">EmbeddedField</h3><p>The <code>EmbeddedField</code> lets you embed a document inside a document. Use it for creating MongoDB embedded documents.
Nest a <code>dict</code> inside a model with the <code>EmbeddedField</code>. The <code>model_container</code> is used to describe the structure of the data stored. </p><div appcodecopy class="highlighter-rouge highlight codehilite"><pre><span></span><code><span class="kn">from</span> <span class="nn">djongo</span> <span class="kn">import</span> <span class="n">models</span>

<span class="k">class</span> <span class="nc">Blog</span><span class="p">(</span><span class="n">models</span><span class="o">.</span><span class="n">Model</span><span class="p">):</span>
    <span class="n">name</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">CharField</span><span class="p">(</span><span class="n">max_length</span><span class="o">=</span><span class="mi">100</span><span class="p">)</span>

    <span class="k">class</span> <span class="nc">Meta</span><span class="p">:</span>
        <span class="n">abstract</span> <span class="o">=</span> <span class="kc">True</span>

<span class="k">class</span> <span class="nc">Entry</span><span class="p">(</span><span class="n">models</span><span class="o">.</span><span class="n">Model</span><span class="p">):</span>
    <span class="n">blog</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">EmbeddedField</span><span class="p">(</span>
        <span class="n">model_container</span><span class="o">=</span><span class="n">Blog</span>
    <span class="p">)</span>    
    <span class="n">headline</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">CharField</span><span class="p">(</span><span class="n">max_length</span><span class="o">=</span><span class="mi">255</span><span class="p">)</span>    

<span class="n">e</span> <span class="o">=</span> <span class="n">Entry</span><span class="p">()</span>
<span class="n">e</span><span class="o">.</span><span class="n">blog</span> <span class="o">=</span> <span class="p">{</span>
    <span class="s1">'name'</span><span class="p">:</span> <span class="s1">'Djongo'</span>
<span class="p">}</span>
<span class="n">e</span><span class="o">.</span><span class="n">headline</span> <span class="o">=</span> <span class="s1">'The Django MongoDB connector'</span>
<span class="n">e</span><span class="o">.</span><span class="n">save</span><span class="p">()</span>
</code></pre><img alt="copy code" src="/assets/images/copy.svg" class="docs-copy"></div><p>Learn more about <a routerlink="/docs/using-django-with-mongodb-data-fields" href="/docs/using-django-with-mongodb-data-fields" jsaction="click:;">embedded fields here</a>.</p><h3 id="arrayfield">ArrayField</h3><p>The <code>ArrayField</code> lets you store a list of embedded documents inside a document. Nest a <code>list</code> of <code>dict</code> inside a model for doing this.</p><div appcodecopy class="highlighter-rouge highlight codehilite"><pre><span></span><code><span class="kn">from</span> <span class="nn">djongo</span> <span class="kn">import</span> <span class="n">models</span>

<span class="k">class</span> <span class="nc">Entry</span><span class="p">(</span><span class="n">models</span><span class="o">.</span><span class="n">Model</span><span class="p">):</span>
    <span class="n">blog</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">ArrayField</span><span class="p">(</span>
        <span class="n">model_container</span><span class="o">=</span><span class="n">Blog</span>
    <span class="p">)</span>    
    <span class="n">headline</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">CharField</span><span class="p">(</span><span class="n">max_length</span><span class="o">=</span><span class="mi">255</span><span class="p">)</span>    

<span class="n">e</span> <span class="o">=</span> <span class="n">Entry</span><span class="p">()</span>
<span class="n">e</span><span class="o">.</span><span class="n">blog</span> <span class="o">=</span> <span class="p">[</span>
    <span class="p">{</span><span class="s1">'name'</span><span class="p">:</span> <span class="s1">'Djongo'</span><span class="p">},</span> <span class="p">{</span><span class="s1">'name'</span><span class="p">:</span> <span class="s1">'Django'</span><span class="p">},</span> <span class="p">{</span><span class="s1">'name'</span><span class="p">:</span> <span class="s1">'MongoDB'</span><span class="p">}</span>
<span class="p">]</span>
<span class="n">e</span><span class="o">.</span><span class="n">headline</span> <span class="o">=</span> <span class="s1">'Djongo is the best Django and MongoDB connector'</span>
<span class="n">e</span><span class="o">.</span><span class="n">save</span><span class="p">()</span>
</code></pre><img alt="copy code" src="/assets/images/copy.svg" class="docs-copy"></div><p>More about <a routerlink="/docs/using-django-with-mongodb-array-field" href="/docs/using-django-with-mongodb-array-field" jsaction="click:;">array fields here</a>.</p><h2 id="querying-data">Querying Data</h2><p>Writing queries for selecting MongoDB data is easy. Querying in Djongo works exactly like in Django
because Djongo translates Django’s ORM queries into MongoDB queries under the hood.
You interact with your data using model managers and QuerySets, which are lazy,
iterable representations of database queries.</p><p>A QuerySet is constructed when you call methods like <code>.all()</code> or <code>.filter()</code>,
and only hits the database when you actually evaluate it. This design allows you to build queries incrementally without immediately hitting the database.
QuerySets make it easy to reason about database access while writing clean Python code.</p><div appcodecopy class="highlighter-rouge highlight codehilite"><pre><span></span><code><span class="kn">from</span> <span class="nn">blog.models</span> <span class="kn">import</span> <span class="n">Post</span>

<span class="c1"># Builds a QuerySet but does not hit the database yet</span>
<span class="n">qs</span> <span class="o">=</span> <span class="n">Post</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">all</span><span class="p">()</span>
</code></pre><img alt="copy code" src="/assets/images/copy.svg" class="docs-copy"></div><h3 id="retrieving-objects">Retrieving Objects</h3><p>The most common methods to retrieve data are <code>.all()</code>, <code>.get()</code>, and <code>.filter()</code>.</p><ul><li><p><code>.all()</code> returns every record as a QuerySet.</p></li><li><p><code>.get()</code> returns a single object and raises an error if none or multiple match.</p></li><li><p><code>.filter()</code> returns a QuerySet matching given conditions.</p></li></ul><p>Filters use field lookups expressed with double underscores (e.g. <code>field__lookup=value</code>) and are
injection safe because Django escapes parameters.</p><div appcodecopy class="highlighter-rouge highlight codehilite"><pre><span></span><code><span class="c1"># Basic retrieval examples</span>
<span class="n">post</span> <span class="o">=</span> <span class="n">Post</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="nb">id</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span>
<span class="n">recent_posts</span> <span class="o">=</span> <span class="n">Post</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">published_date__year</span><span class="o">=</span><span class="mi">2024</span><span class="p">)</span>
<span class="n">all_posts</span> <span class="o">=</span> <span class="n">Post</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">all</span><span class="p">()</span>
</code></pre><img alt="copy code" src="/assets/images/copy.svg" class="docs-copy"></div><h3 id="chaining-filters-and-field-lookups">Chaining Filters and Field Lookups</h3><p>You can chain filters to build complex queries. Each filter call returns a new QuerySet, allowing you to progressively narrow down results. Django supports lookups like <code>exact</code>, <code>iexact</code>, <code>contains</code>, <code>icontains</code>, <code>gte</code>, <code>lte</code>, <code>in</code>, and <code>range</code>.</p><p>QuerySets remain lazy until evaluated, so chaining does not
hit the database immediately. This pattern allows for clean, readable, composable queries.</p><div appcodecopy class="highlighter-rouge highlight codehilite"><pre><span></span><code><span class="n">qs</span> <span class="o">=</span> <span class="n">Post</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">published_date__year</span><span class="o">=</span><span class="mi">2024</span><span class="p">)</span>\
                 <span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">title__icontains</span><span class="o">=</span><span class="s2">"django"</span><span class="p">)</span>\
                 <span class="o">.</span><span class="n">order_by</span><span class="p">(</span><span class="s1">'-published_date'</span><span class="p">)</span>
</code></pre><img alt="copy code" src="/assets/images/copy.svg" class="docs-copy"></div><h3 id="ordering-slicing-and-limiting">Ordering, Slicing, and Limiting</h3><p>You can order results using <code>.order_by()</code> and limit them using Python slicing syntax. Ordering accepts one or more field names, with a <code>-</code> prefix for descending order. Slicing translates to SQL/MongoDB <code>LIMIT</code> and <code>OFFSET</code>. </p><p>You can also use <code>.first()</code> and <code>.last()</code> to get a single record or <code>None</code> if none exist.
These tools let you fetch only the portion of data you need efficiently.</p><div appcodecopy class="highlighter-rouge highlight codehilite"><pre><span></span><code><span class="n">latest_five</span> <span class="o">=</span> <span class="n">Post</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">order_by</span><span class="p">(</span><span class="s1">'-published_date'</span><span class="p">)[:</span><span class="mi">5</span><span class="p">]</span>
<span class="n">first_post</span> <span class="o">=</span> <span class="n">Post</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">order_by</span><span class="p">(</span><span class="s1">'published_date'</span><span class="p">)</span><span class="o">.</span><span class="n">first</span><span class="p">()</span>
</code></pre><img alt="copy code" src="/assets/images/copy.svg" class="docs-copy"></div><h3 id="aggregations-and-related-lookups">Aggregations and Related Lookups</h3><p>Django ORM (and therefore Djongo) supports aggregations with functions like <code>Count</code>,
<code>Sum</code>, <code>Avg</code>, <code>Min</code>, and <code>Max</code>. Use <code>.aggregate()</code> to return a single summary value, or <code>.annotate()</code> to add computed values to each result row. </p><p>You can traverse related fields using double underscores (following <code>ForeignKey</code>, <code>OneToOneField</code>, or <code>ManyToManyField</code>).
This lets you perform joins and calculations without writing raw database queries.</p><div appcodecopy class="highlighter-rouge highlight codehilite"><pre><span></span><code><span class="kn">from</span> <span class="nn">djongo.models</span> <span class="kn">import</span> <span class="n">Count</span>

<span class="n">authors</span> <span class="o">=</span> <span class="n">Author</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">annotate</span><span class="p">(</span><span class="n">num_posts</span><span class="o">=</span><span class="n">Count</span><span class="p">(</span><span class="s1">'post'</span><span class="p">))</span>
<span class="k">for</span> <span class="n">a</span> <span class="ow">in</span> <span class="n">authors</span><span class="p">:</span>
    <span class="nb">print</span><span class="p">(</span><span class="n">a</span><span class="o">.</span><span class="n">name</span><span class="p">,</span> <span class="n">a</span><span class="o">.</span><span class="n">num_posts</span><span class="p">)</span>
</code></pre><img alt="copy code" src="/assets/images/copy.svg" class="docs-copy"></div><h3 id="evaluating-querysets">Evaluating QuerySets</h3><p>A QuerySet executes when it’s evaluated — when you iterate over it, convert it to a list, access a slice, or call <code>.count()</code>, <code>.exists()</code>, <code>.first()</code>, or <code>.last()</code>. </p><p>The results are cached after the first evaluation, so repeated iterations don’t hit the database again unless you call <code>.all()</code> to refresh. This lazy and cached behavior helps minimize database traffic and improve performance. </p><p>You can learn more about <a href="https://docs.djangoproject.com/en/dev/topics/db/queries/">making queries here.</a></p><div appcodecopy class="highlighter-rouge highlight codehilite"><pre><span></span><code><span class="n">qs</span> <span class="o">=</span> <span class="n">Post</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">published_date__year</span><span class="o">=</span><span class="mi">2024</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="nb">list</span><span class="p">(</span><span class="n">qs</span><span class="p">))</span>  <span class="c1"># Executes the query</span>
<span class="nb">print</span><span class="p">(</span><span class="nb">list</span><span class="p">(</span><span class="n">qs</span><span class="p">))</span>  <span class="c1"># Uses the cached results, no new query</span>
</code></pre><img alt="copy code" src="/assets/images/copy.svg" class="docs-copy"></div><h2 id="database-configuration">Database Configuration</h2><p>The <code>settings.py</code> supports (but is not limited to) the following options:</p><table><thead><tr><th>Attribute</th><th>Value</th><th>Description</th></tr></thead><tbody><tr><td>ENGINE</td><td>djongo</td><td>The MongoDB connection engine for interfacing with Django.</td></tr><tr><td>ENFORCE_SCHEMA</td><td>True</td><td>Ensures that the model schema and database schema are exactly the same. Raises <code>Migration Error</code> in case of discrepancy.</td></tr><tr><td>ENFORCE_SCHEMA</td><td>False</td><td>(Default) Implicitly creates collections. Returns missing fields as <code>None</code> instead of raising an exception.</td></tr><tr><td>NAME</td><td>your-db-name</td><td>Specify your database name. This field cannot be left empty.</td></tr><tr><td>LOGGING</td><td>dict</td><td>A <a href="https://docs.python.org/3.6/library/logging.config.html">dictConfig</a> for the type of logging to run on djongo.</td></tr><tr><td>CLIENT</td><td>dict</td><td>A set of key-value pairs that will be passed directly to <a href="http://api.mongodb.com/python/current/api/pymongo/mongo_client.html#pymongo.mongo_client.MongoClient"><code>MongoClient</code></a> as kwargs while creating a new client connection.</td></tr></tbody></table><p>All options except <code>ENGINE</code> and <code>ENFORCE_SCHEMA</code> are the same those listed in the <a href="http://api.mongodb.com/python/current/api/pymongo/mongo_client.html#pymongo.mongo_client.MongoClient">pymongo documentation</a>.</p><div appcodecopy class="highlighter-rouge highlight codehilite"><pre><span></span><code>    <span class="n">DATABASES</span> <span class="o">=</span> <span class="p">{</span>
        <span class="s1">'default'</span><span class="p">:</span> <span class="p">{</span>
            <span class="s1">'ENGINE'</span><span class="p">:</span> <span class="s1">'djongo'</span><span class="p">,</span>
            <span class="s1">'NAME'</span><span class="p">:</span> <span class="s1">'your-db-name'</span><span class="p">,</span>
            <span class="s1">'ENFORCE_SCHEMA'</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span>
            <span class="s1">'CLIENT'</span><span class="p">:</span> <span class="p">{</span>
                <span class="s1">'host'</span><span class="p">:</span> <span class="s1">'host-name or ip address'</span><span class="p">,</span>
                <span class="s1">'port'</span><span class="p">:</span> <span class="n">port_number</span><span class="p">,</span>
                <span class="s1">'username'</span><span class="p">:</span> <span class="s1">'db-username'</span><span class="p">,</span>
                <span class="s1">'password'</span><span class="p">:</span> <span class="s1">'password'</span><span class="p">,</span>
                <span class="s1">'authSource'</span><span class="p">:</span> <span class="s1">'db-name'</span><span class="p">,</span>
                <span class="s1">'authMechanism'</span><span class="p">:</span> <span class="s1">'SCRAM-SHA-1'</span>
            <span class="p">},</span>
            <span class="s1">'LOGGING'</span><span class="p">:</span> <span class="p">{</span>
                <span class="s1">'version'</span><span class="p">:</span> <span class="mi">1</span><span class="p">,</span>
                <span class="s1">'loggers'</span><span class="p">:</span> <span class="p">{</span>
                    <span class="s1">'djongo'</span><span class="p">:</span> <span class="p">{</span>
                        <span class="s1">'level'</span><span class="p">:</span> <span class="s1">'DEBUG'</span><span class="p">,</span>
                        <span class="s1">'propagate'</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span>                        
                    <span class="p">}</span>
                <span class="p">},</span>
             <span class="p">},</span>
        <span class="p">}</span>
    <span class="p">}</span>
</code></pre><img alt="copy code" src="/assets/images/copy.svg" class="docs-copy"></div><h2 id="security-and-integrity-checks">Security and Integrity Checks</h2><p>Djongo allows for checks on data fields before they are saved to the database. Running the correct integrity checks and field value validators before writing data into the database is important. </p><h3 id="enforce-schema">Enforce schema</h3><p>MongoDB is <em>schemaless</em>, which means no schema rules are enforced by the database. You can add and exclude fields per entry and MongoDB will not complain. This can make life easier, especially when there are frequent changes to the data model. Take for example the <code>Blog</code> Model (version 1).</p><div appcodecopy class="highlighter-rouge highlight codehilite"><pre><span></span><code><span class="k">class</span> <span class="nc">Blog</span><span class="p">(</span><span class="n">models</span><span class="o">.</span><span class="n">Model</span><span class="p">):</span>
    <span class="n">name</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">CharField</span><span class="p">(</span><span class="n">max_length</span><span class="o">=</span><span class="mi">100</span><span class="p">)</span>
    <span class="n">tagline</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">TextField</span><span class="p">()</span>
</code></pre><img alt="copy code" src="/assets/images/copy.svg" class="docs-copy"></div><p>You can save several entries into the DB and later modify it to version 2:</p><div appcodecopy class="highlighter-rouge highlight codehilite"><pre><span></span><code><span class="k">class</span> <span class="nc">Blog</span><span class="p">(</span><span class="n">models</span><span class="o">.</span><span class="n">Model</span><span class="p">):</span>
    <span class="n">name</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">CharField</span><span class="p">(</span><span class="n">max_length</span><span class="o">=</span><span class="mi">100</span><span class="p">)</span>
    <span class="n">tagline</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">TextField</span><span class="p">()</span>
    <span class="n">description</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">TextField</span><span class="p">()</span>
</code></pre><img alt="copy code" src="/assets/images/copy.svg" class="docs-copy"></div><p>The modified Model can be saved <strong>without running any migrations</strong>. </p><p>This works fine if you know what you are doing. Consider a query that retrieves entries belonging to both the 'older' model (with just 2 fields) and the current model. What will the value of <code>description</code> now be? To handle such scenarios Djongo comes with the <code>ENFORCE_SCHEMA</code> option. </p><p>When connecting to Djongo you can set <code>ENFORCE_SCHEMA: True</code>. In this case, a <code>MigrationError</code> will be raised when field values are missing from the retrieved documents. You can then check what went wrong. </p><p><code>ENFORCE_SCHEMA: False</code> works by silently setting the missing fields with the value <code>None</code>. If your app is programmed to expect this (which means it is not a bug) you can get away by not calling any migrations.</p><h3 id="validators">Validators</h3><p>Apply validators to each field before they are saved.</p><div appcodecopy class="highlighter-rouge highlight codehilite"><pre><span></span><code><span class="kn">from</span> <span class="nn">django.core.exceptions</span> <span class="kn">import</span> <span class="n">ValidationError</span>
<span class="kn">from</span> <span class="nn">django.utils.translation</span> <span class="kn">import</span> <span class="n">gettext_lazy</span> <span class="k">as</span> <span class="n">_</span>
<span class="kn">from</span> <span class="nn">djongo</span> <span class="kn">import</span> <span class="n">models</span>
<span class="kn">from</span> <span class="nn">django.core.validators</span> <span class="kn">import</span> <span class="n">URLValidator</span>

<span class="k">def</span> <span class="nf">script_injection</span><span class="p">(</span><span class="n">value</span><span class="p">):</span>
    <span class="k">if</span> <span class="n">value</span><span class="o">.</span><span class="n">find</span><span class="p">(</span><span class="s1">'&lt;script&gt;'</span><span class="p">)</span> <span class="o">!=</span> <span class="o">-</span><span class="mi">1</span><span class="p">:</span>
        <span class="k">raise</span> <span class="n">ValidationError</span><span class="p">(</span><span class="n">_</span><span class="p">(</span><span class="s1">'Script injection in </span><span class="si">%(value)s</span><span class="s1">'</span><span class="p">),</span>
                              <span class="n">params</span><span class="o">=</span><span class="p">{</span><span class="s1">'value'</span><span class="p">:</span> <span class="n">value</span><span class="p">})</span>

<span class="k">class</span> <span class="nc">Address</span><span class="p">(</span><span class="n">models</span><span class="o">.</span><span class="n">Model</span><span class="p">)</span>
    <span class="n">city</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">CharField</span><span class="p">(</span><span class="n">max_length</span><span class="o">=</span><span class="mi">50</span><span class="p">)</span>
    <span class="n">homepage</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">URLField</span><span class="p">(</span><span class="n">validators</span><span class="o">=</span><span class="p">[</span><span class="n">URLValidator</span><span class="p">,</span> <span class="n">script_injection</span><span class="p">])</span>
    <span class="k">class</span> <span class="nc">Meta</span><span class="p">:</span>
        <span class="n">abstract</span><span class="o">=</span><span class="kc">True</span>

<span class="k">class</span> <span class="nc">Entry</span><span class="p">(</span><span class="n">models</span><span class="o">.</span><span class="n">Model</span><span class="p">):</span>
    <span class="n">_id</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">ObjectIdField</span><span class="p">()</span>
    <span class="n">address</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">EmbeddedField</span><span class="p">(</span><span class="n">model_container</span><span class="o">=</span><span class="n">Address</span><span class="p">)</span>
</code></pre><img alt="copy code" src="/assets/images/copy.svg" class="docs-copy"></div><h3 id="integrity-checks">Integrity checks</h3><div appcodecopy class="highlighter-rouge highlight codehilite"><pre><span></span><code><span class="k">class</span> <span class="nc">Entry</span><span class="p">(</span><span class="n">models</span><span class="o">.</span><span class="n">Model</span><span class="p">):</span>
    <span class="n">_id</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">ObjectIdField</span><span class="p">()</span>
    <span class="n">address</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">EmbeddedField</span><span class="p">(</span><span class="n">model_container</span><span class="o">=</span><span class="n">Address</span><span class="p">,</span>
                                   <span class="n">null</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
                                   <span class="n">blank</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
</code></pre><img alt="copy code" src="/assets/images/copy.svg" class="docs-copy"></div><p>By setting <code>null=False, blank=False</code> in <code>EmbeddedField</code>, missing values are never stored.</p><h2 id="djongo-manager">Djongo Manager</h2><p>Djongo Manager extends the functionality of the usual <a href="https://docs.djangoproject.com/en/dev/topics/db/managers/">Django Manager</a>. It gives direct access to the pymongo collection API. To use this manager define your manager as <code>DjongoManager</code> in the model.</p><div appcodecopy class="highlighter-rouge highlight codehilite"><pre><span></span><code><span class="k">class</span> <span class="nc">Entry</span><span class="p">(</span><span class="n">models</span><span class="o">.</span><span class="n">Model</span><span class="p">):</span>
    <span class="n">blog</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">EmbeddedField</span><span class="p">(</span>
        <span class="n">model_container</span><span class="o">=</span><span class="n">Blog</span><span class="p">,</span>
    <span class="p">)</span>
    <span class="n">headline</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">CharField</span><span class="p">(</span><span class="n">max_length</span><span class="o">=</span><span class="mi">255</span><span class="p">)</span>    
    <span class="n">objects</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">DjongoManager</span><span class="p">()</span>
</code></pre><img alt="copy code" src="/assets/images/copy.svg" class="docs-copy"></div><p>Use it like the usual Django manager:</p><div appcodecopy class="highlighter-rouge highlight codehilite"><pre><span></span><code><span class="n">post</span> <span class="o">=</span> <span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">pk</span><span class="o">=</span><span class="n">p_key</span><span class="p">)</span>
</code></pre><img alt="copy code" src="/assets/images/copy.svg" class="docs-copy"></div><p>Will <a href="https://docs.djangoproject.com/en/dev/topics/db/queries/#retrieving-a-single-object-with-get">get a model object</a> having primary key <code>p_key</code>.</p><h3 id="using-pymongo-commands">Using PyMongo Commands</h3><p>MongoDB has powerful query syntax and <code>DjongoManager</code> lets you exploit it fully. For the above <code>Entry</code> model define a custom query function:</p><div appcodecopy class="highlighter-rouge highlight codehilite"><pre><span></span><code><span class="k">class</span> <span class="nc">EntryView</span><span class="p">(</span><span class="n">DetailView</span><span class="p">):</span>

    <span class="k">def</span> <span class="nf">get_object</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">queryset</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
        <span class="n">index</span> <span class="o">=</span> <span class="p">[</span><span class="n">i</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">mongo_aggregate</span><span class="p">([</span>
            <span class="p">{</span>
                <span class="s1">'$match'</span><span class="p">:</span> <span class="p">{</span>
                    <span class="s1">'headline'</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">kwargs</span><span class="p">[</span><span class="s1">'path'</span><span class="p">]</span>
                <span class="p">}</span>
            <span class="p">},</span>
        <span class="p">])]</span>

        <span class="k">return</span> <span class="n">index</span>
</code></pre><img alt="copy code" src="/assets/images/copy.svg" class="docs-copy"></div><p class="notice">You can directly <strong>access any</strong> pymongo <a href="https://api.mongodb.com/python/current/">command</a> by prefixing <code>mongo_</code> to the command name. </p><p>For example, to perform <code>aggregate</code> on the BlogPage collection (BlogPage is stored as a table in SQL or a collection in MongoDB) the function name becomes <code>mongo_aggregate</code>. To directly insert a document (instead of <code>.save()</code> a model) use <code>mongo_insert_one()</code></p><h2 id="gridfs">GridFS</h2><p>To save files using <a href="https://www.mongodb.com/docs/manual/core/gridfs/">GridFS</a> you must create a file storage instance of <code>GridFSStorage</code>:</p><div appcodecopy class="highlighter-rouge highlight codehilite"><pre><span></span><code><span class="n">grid_fs_storage</span> <span class="o">=</span> <span class="n">GridFSStorage</span><span class="p">(</span><span class="n">collection</span><span class="o">=</span><span class="s1">'myfiles'</span><span class="p">)</span>
</code></pre><img alt="copy code" src="/assets/images/copy.svg" class="docs-copy"></div><p>In your model define your field as <code>FileField</code> or <code>ImageField</code> as usual:</p><div appcodecopy class="highlighter-rouge highlight codehilite"><pre><span></span><code><span class="n">avatar</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">ImageField</span><span class="p">(</span><span class="n">storage</span><span class="o">=</span><span class="n">grid_fs_storage</span><span class="p">,</span> <span class="n">upload_to</span><span class="o">=</span><span class="s1">''</span><span class="p">)</span>
</code></pre><img alt="copy code" src="/assets/images/copy.svg" class="docs-copy"></div><p>Refer to <a routerlink="/docs/using-django-with-mongodb-gridfs/" href="/docs/using-django-with-mongodb-gridfs" jsaction="click:;">Using GridFSStorage</a> for more details.</p><h2 id="djongocs">DjongoCS</h2><p>Djongo Cloud Server is the fastest way to deploy to the cloud your djongo powered apps. The DjongoCS package and
dependencies come preconfigured and installed on a Google Cloud Platform server. </p><ol><li>Start by <a routerlink="/djongocs/create-account/" href="/djongocs/create-account" jsaction="click:;">creating an account</a>. You will be assigned
a working webserver instance running Django and MongoDB.</li><li>(Optional) Test your instance by entering <code>https://api.djongomapper.com/&lt;username&gt;/</code> in your browser.
The username is what was used while creating the account.</li><li>Login to your <a routerlink="/djongocs/dashboard/" href="/djongocs/dashboard" jsaction="click:;">dashboard</a> and upload your Public SSH key. The command to open a shell
to your instance will appear in the dashboard. You can upload your app specific Django scripts to the server.</li></ol><h3 id="generate-access-token">Generate access token</h3><p>Once logged into the <a routerlink="/djongocs/dashboard/" href="/djongocs/dashboard" jsaction="click:;">dashboard</a> click on <em>generate token</em>. This generates and installs a pass token
needed for downloading the latest version of djongo for local development. Copy and add the generated token into the <code>~/.netrc</code> file located in
your home directory.</p><div appcodecopy class="highlighter-rouge highlight codehilite"><pre><span></span><code>machine<span class="w"> </span>pypi.djongomapper.com
login<span class="w"> </span>&lt;djongocs<span class="w"> </span>username&gt;
password<span class="w"> </span>&lt;generated<span class="w"> </span>token&gt;
</code></pre><img alt="copy code" src="/assets/images/copy.svg" class="docs-copy"></div><p>You can then install the latest version of djongo:</p><div appcodecopy class="highlighter-rouge highlight codehilite"><pre><span></span><code>pip<span class="w"> </span>install<span class="w"> </span>--extra-index-url<span class="w"> </span>https://pypi.djongomapper.com/latest-updates/<span class="w"> </span>djongo
</code></pre><img alt="copy code" src="/assets/images/copy.svg" class="docs-copy"></div><p><strong>Make sure</strong> to safely install and store the pass token inside the <code>~/.netrc</code> file.
The pass token is not saved on the DjongoCS server locally.</p><h3 id="ssh">SSH</h3><p>On account creation you install your public SSH key at the dashboard.
This gives the SSH access to the VM instance for uploading a <a href="https://docs.djangoproject.com/en/dev/intro/tutorial01/">Django App</a>. Once the key is installed, the dashboard displays the SSH port number over which you can connect to the VM instance. </p><p>Establish a secure shell connection using:</p><div appcodecopy class="highlighter-rouge highlight codehilite"><pre><span></span><code>ssh<span class="w"> </span>&lt;username&gt;@api.djongomapper.com<span class="w"> </span>-p<span class="w"> </span>&lt;port&gt;<span class="w"> </span>
</code></pre><img alt="copy code" src="/assets/images/copy.svg" class="docs-copy"></div><p>The <code>username</code> is the same as the username used while creating the DjongoCS account.</p><p>When you create an account on DjongoCS you get a unique URL path assigned to you. The Django views that you
create for servicing your API can be accessed
and extended further starting from the base URL: <code>https://api.djongomapper.com/&lt;username&gt;</code></p><h3 id="launching-the-app">Launching the App</h3><p>Establishing an SSH connection to your server logs you into the <code>/home/$USER</code> directory. The typical home directory
structure looks like:</p><div appcodecopy class="highlighter-rouge highlight codehilite"><pre><span></span><code>~home
<span class="p">|</span><span class="w"> </span>--<span class="w"> </span>.ssh/
<span class="p">|</span><span class="w"> </span>--<span class="w"> </span>site/
<span class="p">|</span><span class="w">   </span>--<span class="w"> </span>api/
<span class="p">|</span><span class="w">     </span>--<span class="w"> </span>settings.py
<span class="p">|</span><span class="w">     </span>--<span class="w"> </span>urls.py
<span class="p">|</span><span class="w">   </span>--<span class="w"> </span>apps/
<span class="p">|</span><span class="w">     </span>--<span class="w"> </span>app1/
<span class="p">|</span><span class="w">       </span>--<span class="w"> </span>views.py
<span class="p">|</span><span class="w">       </span>--<span class="w"> </span>models.py
<span class="p">|</span><span class="w">     </span>--<span class="w"> </span>app2/
<span class="p">|</span><span class="w">       </span>--<span class="w"> </span>views.py
<span class="p">|</span><span class="w">       </span>--<span class="w"> </span>models.py
</code></pre><img alt="copy code" src="/assets/images/copy.svg" class="docs-copy"></div><p>In your <code>urls.py</code> if you add an entry like <code>path('hello/', app1.views.hello)</code>, the URL path becomes
<code>https://api.djongomapper.com/&lt;username&gt;/hello</code></p><h2 id="djongocs-features">DjongoCS Features</h2><p class="notice-info">Features under development on DjongoCS are not a part of the standard Djongo package. </p><p>DjongoCS supports multiple features of MongoDB including:</p><h3 id="indexes">Indexes</h3><p>Support for indexes provided by MongoDB, for example 2dSphere Index, Text Index and Compound Indexes.</p><h3 id="model-query">Model Query</h3><p>Support for GeoSpatial Queries and Tailable Cursors.</p><h3 id="model-update">Model Update</h3><p>Unordered and Ordered Bulk Writes.</p><h3 id="database-transactions">Database Transactions</h3><p>Atomic multi document transactions with commit and rollback support.</p><h3 id="schema-validation-and-model-creation">Schema Validation and Model Creation</h3><p>Automatic JSON Schema validation document generation and options to add Read and Write Concerns for the Models.</p><h3 id="aggregation-operators">Aggregation Operators</h3><p>Support for various aggregation operators provided by MongoDB.</p><h2 id="contribute">Contribute</h2><p>If you think djongo is useful, <strong>please share it</strong> with the world! Your endorsements and online reviews will help get more support for this project.</p><p>You can contribute to the source code or the documentation by creating a simple pull request! You may want to refer to the design documentation to get an idea on how <a routerlink="/docs/django-mongodb-connector-design-document/" href="/docs/django-mongodb-connector-design-document" jsaction="click:;">Django MongoDB connector</a> is implemented.</p></ng-component><!----></div><aside _ngcontent-ng-c2889142148 class="nav-sticky aside-right"><nav _ngcontent-ng-c2889142148 class="nav nav-toc"><h3 _ngcontent-ng-c2889142148><i _ngcontent-ng-c2889142148 class="fas fa-file-alt"></i> On This Page</h3><ul _ngcontent-ng-c2889142148><!----></ul></nav></aside></div></ng-component><!----></div><div _ngcontent-ng-c2830357685 id="footer" class="page-footer"><footer _ngcontent-ng-c2830357685><aside _ngcontent-ng-c2830357685 class="l-fixed-notice cookie-notice open"><p _ngcontent-ng-c2830357685>We use cookies to enhance user experience. You consent to their usage by browsing this site. <button _ngcontent-ng-c2830357685 id="cookie-accept" class="btn btn-green" jsaction="click:;">Accept</button></p></aside><div _ngcontent-ng-c2830357685 class="page-footer-copyright">© 2025 Doableware AB.</div></footer></div></div></app-root>
<script>
  window.ga = function () {
    ga.q.push(arguments)
  };
  ga.q = [];
  ga.l = +new Date;
  ga('create', 'UA-75159067-1', 'auto');
  ga('set', 'anonymizeIp', false);
  ga('send', 'pageview')
</script>
<script src="https://www.google-analytics.com/analytics.js" async></script>
<link rel="modulepreload" href="chunk-GTGB5SJ3.js"><link rel="modulepreload" href="chunk-HEUFHRRO.js"><link rel="modulepreload" href="chunk-RYXYKL7J.js"><link rel="modulepreload" href="chunk-YECZU7CY.js"><link rel="modulepreload" href="chunk-UZ35QZ23.js"><link rel="modulepreload" href="chunk-FDEVB4XX.js"><script src="polyfills-BUUDEW7V.js" type="module"></script><script src="main-TEK63YGN.js" type="module"></script>
<link rel="modulepreload" href="chunk-TTHFXBLJ.js">
<link rel="modulepreload" href="chunk-VWVSK2JB.js">

<script id="ng-state" type="application/json">{"__nghData__":[{"t":{"0":"t1","2":"t2","3":"t3"},"c":{"0":[],"2":[],"3":[]}},{},{"d":[3,4,6],"t":{"6":"t21","20":"t22"},"c":{"12":[{"i":"c2863985590","r":1}],"20":[]}},{"t":{"6":"t0","12":"t4"},"c":{"6":[],"14":[{"i":"c2889142148","r":1}]},"d":[9,10,12]}]}</script></body></html>